// var n;
// var $bundleConfig = require("./BundleConfig");
// var $logManager = require("./LogManager");
// var $singletonManager = require("./SingletonManager");
// var $resKeeper = require("./ResKeeper");
// var $resLoader = require("./ResLoader");
// var $resUtil = require("./ResUtil");
// var $uIView = require("./UIView");
// var f = (function (e) {
//     function t() {
//         var t = (null !== e && e.apply(this, arguments)) || this;
//         t._isOpening = !1;
//         t._openQueue = [];
//         t._uiConf = new Map();
//         t._uiList = new Map();
//         return t;
//     }
//     __extends(t, e);
//     t.prototype.open = function (e, t) {
//         var o = this;
//         var n = [];
//         for (var i = 2; i < arguments.length; i++) {
//             n[i - 2] = arguments[i];
//         }
//         var a = this._uiConf.get(e);
//         if (a) {
//             var r = a[t];
//             if (r) {
//                 r.args = n;
//                 if (this._isOpening) {
//                     $logManager.LogMgr.warn("正在打开其他界面," + t + "加入等待队列");
//                     var c = {
//                         bundleName: e,
//                         uiName: t,
//                         uiInfo: r
//                     };
//                     this._openQueue.push(c);
//                 } else {
//                     var l = this._uiList.get(e + "_" + t);
//                     if (cc.isValid(l, !0)) {
//                         var u = l.node.zIndex;
//                         this._uiList.forEach(function (e) {
//                             if (e.node.zIndex > u) {
//                                 o.close(e);
//                             }
//                         });
//                         return void l.onResume.apply(l, n);
//                     }
//                     this._show(e, t, r);
//                 }
//             } else {
//                 $logManager.LogMgr.warn("Bundle:" + e + " UI:" + t + " 未注册 UI配置");
//             }
//         } else {
//             $logManager.LogMgr.warn("Bundle:" + e + " 未注册 UI配置");
//         }
//     };
//     t.prototype.close = function (e) {
//         var t = e.bundleName;
//         var o = e.uiName;
//         e.showHideViews();
//         e.rmEvents();
//         e.onClose();
//         this._uiList.delete(t + "_" + o);
//         if (!e.isCache) {
//             var n = e.node.getComponentsInChildren($resKeeper.default);
//             for (var i = 0; i < n.length; i++) {
//                 n[i].node.destroy();
//             }
//         }
//         e.node.removeFromParent(!0);
//     };
//     t.prototype.closeView = function (e, t) {
//         var o = e + "_" + t;
//         var n = this._uiList.get(o);
//         if (n) {
//             this.close(n);
//         } else {
//             $logManager.LogMgr.warn("UIManager close view error: bundle: " + e + ", view: " + n);
//         }
//     };
//     t.prototype.closeAll = function () {
//         var e = this;
//         this._uiList.forEach(function (t) {
//             e.close(t);
//         });
//     };
//     t.prototype.register = function (e, t) {
//         if (this._uiConf.has(e)) {
//             $logManager.LogMgr.warn("Bundle:" + e + " 重复注册 UI配置");
//         }
//         this._uiConf.set(e, t);
//     };
//     t.prototype.unRegister = function (e) {
//         this._uiConf.delete(e);
//     };
//     t.prototype.unRegisterAll = function () {
//         this._uiConf.clear();
//     };
//     t.prototype.getViewByName = function (e, t) {
//         var o = e + "_" + t;
//         return this._uiList.get(o);
//     };
//     t.prototype.getAllViews = function () {
//         return Array.from(this._uiList.values());
//     };
//     t.prototype._show = function (e, t, o) {
//         return __awaiter(this, void 0, void 0, function () {
//             var n;
//             var i;
//             var a;
//             var l;
//             var u;
//             var f;
//             var g;
//             var _;
//             var y;
//             return __generator(this, function (r) {
//                 switch (r.label) {
//                     case 0:
//                         this._isOpening = !0;
//                         n = null;
//                         if (o.block) {
//                             n = this._getBlockInputNode(e, t);
//                             if (o.mask) {
//                                 (i = n.addComponent(cc.Sprite)).sizeMode = cc.Sprite.SizeMode.CUSTOM;
//                                 $resLoader.default
//                                     .loadRes($bundleConfig.BundleNames.Resouce, "texture/singleColor", cc.SpriteFrame)
//                                     .then(function (e) {
//                                         i.spriteFrame = e;
//                                     });
//                                 n.color = cc.color(0, 0, 0);
//                                 n.opacity = 230;
//                             }
//                         }
//                         return [4, $resLoader.default.loadBundle(e)];
//                     case 1:
//                         if ((a = r.sent())) {
//                             return (l = o.prefab), [4, $resLoader.default.loadRes(a, l, cc.Prefab)];
//                         } else {
//                             return $logManager.LogMgr.error("Unable to find bundle " + e), [2, this._autoExecNext(n)];
//                         }
//                     case 2:
//                         if ((u = r.sent())) {
//                             return (
//                                 (f = cc.director.getScene().getChildByName("Canvas")),
//                                 (g = f.getChildByName("UIRoot")),
//                                 (_ = $resUtil.ResUtil.instantiate(u)),
//                                 (y = _.getComponent($uIView.default)),
//                                 g.addChild(_),
//                                 this._adaptiveCenter(_),
//                                 (_.zIndex = this._uiList.size + 1),
//                                 (_.name = e + "_" + t),
//                                 y
//                                     ? (this._autoExecNext(n, _),
//                                       y.init(e, t, o.args),
//                                       this._uiList.set(e + "_" + t, y),
//                                       $logManager.LogMgr.debug("UIManager open view: " + t),
//                                       [2])
//                                     : ($logManager.LogMgr.warn("UI:" + t + " 未注册 UIView"),
//                                       [2, this._autoExecNext(n)])
//                             );
//                         } else {
//                             return (
//                                 $logManager.LogMgr.error("Unable to find bundle " + e + " prefab " + l),
//                                 [2, this._autoExecNext(n)]
//                             );
//                         }
//                 }
//             });
//         });
//     };
//     t.prototype._autoExecNext = function (e, t) {
//         this._isOpening = !1;
//         if (t && e) {
//             e.parent = t;
//             e.zIndex = -1;
//             e.setPosition(cc.v2(0, 0));
//         } else {
//             if (!(null == e)) {
//                 e.removeFromParent();
//             }
//         }
//         if (!(this._openQueue.length <= 0)) {
//             var o = this._openQueue.shift();
//             this._show(o.bundleName, o.uiName, o.uiInfo);
//         }
//     };
//     t.prototype._getBlockInputNode = function (e, t) {
//         var o = new cc.Node(e + "_" + t + "_block");
//         o.setContentSize(cc.winSize);
//         o.addComponent(cc.BlockInputEvents);
//         cc.director.getScene().getChildByName("Canvas").getChildByName("UIBlock").addChild(o);
//         o.zIndex = 999;
//         return o;
//     };
//     t.prototype._adaptiveCenter = function () {};
//     return t;
// })($singletonManager.SingletonMgr);
// exports.default = f.getInstance();

// import { LogMgr } from "./LogManager";
// import { SingletonMgr } from "./SingletonManager";
// import ResKeeper from "./ResKeeper";
// import ResourceLoader from "./ResLoader";
// import {ResUtil} from "./ResUtil";
// import UIView from "./UIView";
// import { BundleNames } from "./BundleConfig";

// class UIManager extends SingletonMgr {
//     private _isOpening: boolean = false;
//     private _openQueue: Array<any> = [];
//     private _uiConf: Map<string, any> = new Map();
//     private _uiList: Map<string, any> = new Map();

//     /**
//      * 打开界面
//      * @param e - bundle 名称
//      * @param t - UI 名称
//      * @param args - 其他参数
//      * 建议方法名：openView
//      */
//     public open(e: string, t: string, args?: any): void {
//         const uiInfo = this._uiConf.get(e);
//         if (uiInfo) {
//             const uiConfig = uiInfo[t];
//             if (uiConfig) {
//                 uiConfig.args = args;
//                 if (this._isOpening) {
//                     LogMgr.warn(`正在打开其他界面, ${t} 加入等待队列`);
//                     const queueItem = {
//                         bundleName: e,
//                         uiName: t,
//                         uiInfo: uiConfig
//                     };
//                     this._openQueue.push(queueItem);
//                 } else {
//                     const uiInstance = this._uiList.get(`${e}_${t}`);
//                     if (cc.isValid(uiInstance, true)) {
//                         const zIndex = uiInstance.node.zIndex;
//                         this._uiList.forEach((ui) => {
//                             if (ui.node.zIndex > zIndex) {
//                                 this.close(ui);
//                             }
//                         });
//                         uiInstance.onResume(...args);
//                     } else {
//                         this._show(e, t, uiConfig);
//                     }
//                 }
//             } else {
//                 LogMgr.warn(`Bundle: ${e} UI: ${t} 未注册 UI配置`);
//             }
//         } else {
//             LogMgr.warn(`Bundle: ${e} 未注册 UI配置`);
//         }
//     }

//     /**
//      * 关闭界面
//      * @param uiView - 界面实例
//      * 建议方法名：closeViewInstance
//      */
//     public close(uiView: UIView): void {
//         const bundleName = uiView.bundleName;
//         const uiName = uiView.uiName;
//         uiView.showHideViews();
//         uiView.rmEvents();
//         uiView.onClose();
//         this._uiList.delete(`${bundleName}_${uiName}`);
//         if (!uiView.isCache) {
//             const resKeepers = uiView.node.getComponentsInChildren(ResKeeper);
//             for (let i = 0; i < resKeepers.length; i++) {
//                 resKeepers[i].node.destroy();
//             }
//         }
//         uiView.node.removeFromParent(true);
//     }

//     /**
//      * 关闭指定的界面
//      * @param e - bundle 名称
//      * @param t - UI 名称
//      * 建议方法名：closeSpecificView
//      */
//     public closeView(e: string, t: string): void {
//         const key = `${e}_${t}`;
//         const uiInstance = this._uiList.get(key);
//         if (uiInstance) {
//             this.close(uiInstance);
//         } else {
//             LogMgr.warn(`UIManager close view error: bundle: ${e}, view: ${t}`);
//         }
//     }

//     /**
//      * 关闭所有界面
//      * 建议方法名：closeAllViews
//      */
//     public closeAll(): void {
//         this._uiList.forEach((uiInstance) => {
//             this.close(uiInstance);
//         });
//     }

//     /**
//      * 注册 UI 配置
//      * @param e - bundle 名称
//      * @param t - UI 配置
//      * 建议方法名：registerUIConfig
//      */
//     public register(e: string, t: any): void {
//         if (this._uiConf.has(e)) {
//             LogMgr.warn(`Bundle: ${e} 重复注册 UI配置`);
//         }
//         this._uiConf.set(e, t);
//     }

//     /**
//      * 注销 UI 配置
//      * @param e - bundle 名称
//      * 建议方法名：unregisterUIConfig
//      */
//     public unRegister(e: string): void {
//         this._uiConf.delete(e);
//     }

//     /**
//      * 注销所有 UI 配置
//      * 建议方法名：unregisterAllUIConfigs
//      */
//     public unRegisterAll(): void {
//         this._uiConf.clear();
//     }

//     /**
//      * 根据名称获取界面实例
//      * @param e - bundle 名称
//      * @param t - UI 名称
//      * @returns 界面实例
//      * 建议方法名：getViewInstanceByName
//      */
//     public getViewByName(e: string, t: string): any {
//         const key = `${e}_${t}`;
//         return this._uiList.get(key);
//     }

//     /**
//      * 获取所有界面实例
//      * @returns 所有界面实例
//      * 建议方法名：getAllViewInstances
//      */
//     public getAllViews(): any[] {
//         return Array.from(this._uiList.values());
//     }

//     /**
//      * 显示界面
//      * @param e - bundle 名称
//      * @param t - UI 名称
//      * @param o - UI 配置
//      * 建议方法名：showView
//      */
//     private async _show(e: string, t: string, o: any): Promise<void> {
//         this._isOpening = true;
//         let blockNode: cc.Node | null = null;
//         if (o.block) {
//             blockNode = this._getBlockInputNode(e, t);
//             if (o.mask) {
//                 const sprite = blockNode.addComponent(cc.Sprite);
//                 sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
//                 const spriteFrame = await ResourceLoader.loadRes(BundleNames.Resouce, "texture/singleColor", cc.SpriteFrame);
//                 sprite.spriteFrame = spriteFrame;
//                 blockNode.color = cc.color(0, 0, 0);
//                 blockNode.opacity = 230;
//             }
//         }

//         const bundle = await ResourceLoader.loadBundle(e);
//         if (bundle) {
//             const prefab = o.prefab;
//             const prefabInstance = await ResourceLoader.loadRes(bundle, prefab, cc.Prefab);
//             if (prefabInstance) {
//                 const canvas = cc.director.getScene().getChildByName("Canvas");
//                 const uiRoot = canvas.getChildByName("UIRoot");
//                 const uiNode = ResUtil.instantiate(prefabInstance);
//                 const uiView = uiNode.getComponent(UIView);
//                 uiRoot.addChild(uiNode);
//                 this._adaptiveCenter(uiNode);
//                 uiNode.zIndex = this._uiList.size + 1;
//                 uiNode.name = `${e}_${t}`;
//                 if (uiView) {
//                     this._autoExecNext(blockNode, uiNode);
//                     uiView.init(e, t, o.args);
//                     this._uiList.set(`${e}_${t}`, uiView);
//                     LogMgr.debug(`UIManager open view: ${t}`);
//                 } else {
//                     LogMgr.warn(`UI: ${t} 未注册 UIView`);
//                     this._autoExecNext(blockNode);
//                 }
//             } else {
//                 LogMgr.error(`Unable to find bundle ${e} prefab ${prefab}`);
//                 this._autoExecNext(blockNode);
//             }
//         } else {
//             LogMgr.error(`Unable to find bundle ${e}`);
//             this._autoExecNext(blockNode);
//         }
//     }

//     /**
//      * 自动执行下一个打开操作
//      * @param blockNode - 阻挡节点
//      * @param uiNode - UI 节点
//      * 建议方法名：autoExecuteNext
//      */
//     private _autoExecNext(blockNode: cc.Node | null, uiNode?: cc.Node): void {
//         this._isOpening = false;
//         if (uiNode && blockNode) {
//             blockNode.parent = uiNode;
//             blockNode.zIndex = -1;
//             blockNode.setPosition(cc.v2(0, 0));
//         } else if (blockNode) {
//             blockNode.removeFromParent();
//         }

//         if (this._openQueue.length > 0) {
//             const next = this._openQueue.shift();
//             this._show(next.bundleName, next.uiName, next.uiInfo);
//         }
//     }

//     /**
//      * 获取阻挡输入节点
//      * @param e - bundle 名称
//      * @param t - UI 名称
//      * @returns 阻挡输入节点
//      * 建议方法名：getBlockInputNode
//      */
//     private _getBlockInputNode(e: string, t: string): cc.Node {
//         const blockNode = new cc.Node(`${e}_${t}_block`);
//         blockNode.setContentSize(cc.winSize);
//         blockNode.addComponent(cc.BlockInputEvents);
//         cc.director.getScene().getChildByName("Canvas").getChildByName("UIBlock").addChild(blockNode);
//         blockNode.zIndex = 999;
//         return blockNode;
//     }

//     /**
//      * 自适应居中
//      * @param node - 需要居中的节点
//      * 建议方法名：adaptiveCenter
//      */
//     private _adaptiveCenter(node: cc.Node): void {
//         // 自适应居中的实现
//     }
// }

// export default UIManager.getInstance();

import { LogMgr } from "./LogManager";
import { SingletonBase } from "./SingletonManager";
import ResKeeper from "./ResKeeper";
import ResourceLoader from "./ResLoader";
import { ResourceUtil } from "./ResUtil";
import UIViewBase from "./UIView";
import { BundleNames } from "./BundleConfig";

/** 建议名称：UIManager */
class ViewManager extends SingletonBase {
    private _isOpening: boolean = false;
    private _openQueue: Array<any> = [];
    private _uiConf: Map<string, any> = new Map();
    private _uiList: Map<string, any> = new Map();

    /**
     * 建议方法名：openView
     * 打开界面
     * @param bundleName - bundle 名称
     * @param uiName - UI 名称
     * @param args - 其他参数
     */
    public open(bundleName: string, uiName: string, args?: any): void {
        const uiConfigMap = this._uiConf.get(bundleName);
        if (uiConfigMap) {
            const uiConfig = uiConfigMap[uiName];
            if (uiConfig) {
                uiConfig.args = args;
                if (this._isOpening) {
                    LogMgr.warn(`正在打开其他界面, ${uiName} 加入等待队列`);
                    const queueItem = { bundleName, uiName, uiInfo: uiConfig };
                    this._openQueue.push(queueItem);
                } else {
                    const instanceKey = `${bundleName}_${uiName}`;
                    const uiInstance = this._uiList.get(instanceKey);
                    if (cc.isValid(uiInstance, true)) {
                        const zIndex = uiInstance.node.zIndex;
                        this._uiList.forEach((ui) => {
                            if (ui.node.zIndex > zIndex) {
                                this.close(ui);
                            }
                        });
                        uiInstance.onResume(...args);
                    } else {
                        this._show(bundleName, uiName, uiConfig);
                    }
                }
            } else {
                LogMgr.warn(`Bundle: ${bundleName} UI: ${uiName} 未注册 UI配置`);
            }
        } else {
            LogMgr.warn(`Bundle: ${bundleName} 未注册 UI配置`);
        }
    }

    /**
     * 建议方法名：closeViewInstance
     * 关闭界面
     * @param uiView - 界面实例
     */
    public close(uiView: UIViewBase): void {
        const bundleName = uiView.bundleName;
        const uiName = uiView.uiName;
        uiView.showHideViews();
        uiView.rmEvents();
        uiView.onClose();
        this._uiList.delete(`${bundleName}_${uiName}`);
        if (!uiView.isCache) {
            const resKeepers = uiView.node.getComponentsInChildren(ResKeeper);
            for (let i = 0; i < resKeepers.length; i++) {
                resKeepers[i].node.destroy();
            }
        }
        uiView.node.removeFromParent(true);
    }

    /**
     * 建议方法名：closeSpecificView
     * 关闭指定的界面
     * @param bundleName - bundle 名称
     * @param uiName - UI 名称
     */
    public closeView(bundleName: string, uiName: string): void {
        const instanceKey = `${bundleName}_${uiName}`;
        const uiInstance = this._uiList.get(instanceKey);
        if (uiInstance) {
            this.close(uiInstance);
        } else {
            LogMgr.warn(`UIManager close view error: bundle: ${bundleName}, view: ${uiName}`);
        }
    }

    /**
     * 建议方法名：closeAllViews
     * 关闭所有界面
     */
    public closeAllViews(): void {
        this._uiList.forEach((uiInstance) => {
            this.close(uiInstance);
        });
    }

    /**
     * 建议方法名：registerUIConfig
     * 注册 UI 配置
     * @param bundleName - bundle 名称
     * @param uiConfig - UI 配置
     */
    public registerUIConfig(bundleName: string, uiConfig: any): void {
        if (this._uiConf.has(bundleName)) {
            LogMgr.warn(`Bundle: ${bundleName} 重复注册 UI配置`);
        }
        this._uiConf.set(bundleName, uiConfig);
    }

    /**
     * 建议方法名：unregisterUIConfig
     * 注销 UI 配置
     * @param bundleName - bundle 名称
     */
    public unregisterUIConfig(bundleName: string): void {
        this._uiConf.delete(bundleName);
    }

    /**
     * 建议方法名：unregisterAllUIConfigs
     * 注销所有 UI 配置
     */
    public unregisterAllUIConfigs(): void {
        this._uiConf.clear();
    }

    /**
     * 建议方法名：getViewInstanceByName
     * 根据名称获取界面实例
     * @param bundleName - bundle 名称
     * @param uiName - UI 名称
     * @returns 界面实例
     */
    public getViewByName(bundleName: string, uiName: string): any {
        const instanceKey = `${bundleName}_${uiName}`;
        return this._uiList.get(instanceKey);
    }

    /**
     * 建议方法名：getAllViewInstances
     * 获取所有界面实例
     * @returns 所有界面实例
     */
    public getAllViews(): any[] {
        return Array.from(this._uiList.values());
    }

    /**
     * 建议方法名：showView
     * 显示界面
     * @param bundleName - bundle 名称
     * @param uiName - UI 名称
     * @param uiConfig - UI 配置
     */
    private async _show(bundleName: string, uiName: string, uiConfig: any): Promise<void> {
        this._isOpening = true;
        let blockNode: cc.Node | null = null;
        if (uiConfig.block) {
            blockNode = this._getBlockInputNode(bundleName, uiName);
            if (uiConfig.mask) {
                const sprite = blockNode.addComponent(cc.Sprite);
                sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
                const spriteFrame = await ResourceLoader.loadRes(BundleNames.Resouce, "texture/singleColor", cc.SpriteFrame);
                sprite.spriteFrame = spriteFrame;
                blockNode.color = cc.color(0, 0, 0);
                blockNode.opacity = 230;
            }
        }

        const bundle = await ResourceLoader.loadBundle(bundleName);
        if (bundle) {
            const prefab = uiConfig.prefab;
            const prefabInstance = await ResourceLoader.loadRes(bundle, prefab, cc.Prefab);
            if (prefabInstance) {
                const canvas = cc.director.getScene().getChildByName("Canvas");
                const uiRoot = canvas.getChildByName("UIRoot");
                const uiNode = ResourceUtil.instantiate(prefabInstance);
                const uiView = uiNode.getComponent(UIViewBase);
                uiRoot.addChild(uiNode);
                this._adaptiveCenter(uiNode);
                uiNode.zIndex = this._uiList.size + 1;
                uiNode.name = `${bundleName}_${uiName}`;
                if (uiView) {
                    this._autoExecNext(blockNode, uiNode);
                    uiView.init(bundleName, uiName, uiConfig.args);
                    this._uiList.set(`${bundleName}_${uiName}`, uiView);
                    LogMgr.debug(`UIManager open view: ${uiName}`);
                } else {
                    LogMgr.warn(`UI: ${uiName} 未注册 UIView`);
                    this._autoExecNext(blockNode);
                }
            } else {
                LogMgr.error(`Unable to find bundle ${bundleName} prefab ${prefab}`);
                this._autoExecNext(blockNode);
            }
        } else {
            LogMgr.error(`Unable to find bundle ${bundleName}`);
            this._autoExecNext(blockNode);
        }
    }

    /**
     * 建议方法名：autoExecuteNext
     * 自动执行下一个打开操作
     * @param blockNode - 阻挡节点
     * @param uiNode - UI 节点
     */
    private _autoExecNext(blockNode: cc.Node | null, uiNode?: cc.Node): void {
        this._isOpening = false;
        if (uiNode && blockNode) {
            blockNode.parent = uiNode;
            blockNode.zIndex = -1;
            blockNode.setPosition(cc.v2(0, 0));
        } else if (blockNode) {
            blockNode.removeFromParent();
        }

        if (this._openQueue.length > 0) {
            const next = this._openQueue.shift();
            this._show(next.bundleName, next.uiName, next.uiInfo);
        }
    }

    /**
     * 建议方法名：getBlockInputNode
     * 获取阻挡输入节点
     * @param bundleName - bundle 名称
     * @param uiName - UI 名称
     * @returns 阻挡输入节点
     */
    private _getBlockInputNode(bundleName: string, uiName: string): cc.Node {
        const blockNode = new cc.Node(`${bundleName}_${uiName}_block`);
        blockNode.setContentSize(cc.winSize);
        blockNode.addComponent(cc.BlockInputEvents);
        cc.director.getScene().getChildByName("Canvas").getChildByName("UIBlock").addChild(blockNode);
        blockNode.zIndex = 999;
        return blockNode;
    }

    /**
     * 建议方法名：adaptiveCenter
     * 自适应居中
     * @param uiNode - 需要居中的节点
     */
    private _adaptiveCenter(uiNode: cc.Node): void {
        // 自适应居中的实现
    }
}

export default ViewManager.getInstance();